概要
このセクションでは、SmartREST プロトコル、使用されるデータ形式、および SmartREST テンプレートの構造と登録について説明します。
組み込みメッセージとエラーについても説明します。
詳細な手順については、REST インターフェースの使用 を参照してください。
Things Cloud REST APIは、ほとんどの環境から簡単に使用できる汎用 IoT プロトコルを提供します。これはどのような IoT ユースケースにもアドホックに適応させることができ、また標準的なインターネット通信およびセキュリティ メカニズムを利用します。適切な標準技術を利用しているため、独自 IoT プロトコルと比べ先進的である一方、ローエンドのマイクロコントローラまたは低帯域幅通信チャネルなど、非常に制約の多い環境には課題をもたらすことがあります。
こうした環境向けに、Things Cloudは、いわゆる「SmartREST」プロトコルを提供します。SmartREST は以下のように、標準技術の利点と特別仕様のプロトコルの利点を同時に提供するものです。
- 標準 HTTP 技術の使用により、どのようなネットワークでもそのまま機能します。
- HTTPの認証と暗号化に対応します。
- プロトコルのバージョニングにも適切に対処します。
- ネットワーク トラフィックの使用量は、通常の操作ではペイロードデータのみを転送することで、最適化されたプロトコルのものに近いです。
- CSV(カンマ区切り値)を基本としているので、C ベース環境からも容易に処理できます。
- 時計のないデバイス向けに、サーバーが生成するタイムスタンプに対応します。
次のセクションでは、SmartREST の背景にある概念と、使用する基本プロトコルについて説明します。SmartRESTは 後述の通り、テンプレートを使ってメタデータをペイロードデータから分離する処理を基本としています。最後に、SmartREST を使用してデータを送受信する方法を説明します。
SmartREST の動作方法
下の画像は、SmartREST の動作を図示したものです。デバイスおよび他のクライアントは、Things Cloud 上の専用 SmartREST エンドポイントに接続し、それぞれのデータをカンマ区切り値からなる行として送信します。これらの行は Things Cloud の SmartREST プロキシにより、標準の Things Cloud REST APIリクエストへと展開されます。同様に、Things Cloud からのレスポンスは、通常の JSON 形式からプロキシによってカンマ区切り値に圧縮された後、デバイスに返却されます。
Things Cloud はカンマ区切り値をどのようにして意味のある REST リクエストとして解釈するのか?
まず、これを行うためにデバイスはテンプレートをThings Cloudに登録します。テンプレートは、展開された REST リクエスト形式をプレースホルダーと一緒に保持しており、その中へ Things Cloud の SmartREST プロキシが連続的にカンマ区切り値を挿入します。応答の場合、テンプレートはカンマ区切り値を構築するために、構造化された REST レスポンスからどの値を抽出するかを記述します。
テンプレートは、デバイスのソフトウェアまたはファームウェアのバージョンに関連付けられます。通常、デバイスまたはアプリケーションに固有な実装は、用途に応じたリクエストタイプに対応しており、決まった範囲のリクエストを発行します。同じ実装のデバイスはすべて、同じ一連のリクエストタイプを共有するのです。したがって、テンプレートは実装段階で定義できます。テンプレートを Things Cloud で使用できるようにするため、特定の実装を伴う最初のデバイスがそのテンプレートを送信し、すべての同様のデバイスで利用できるようにします。
以下の図は、このプロセスを表したものです。「Device_1.0」のバージョンを実装したデバイスが SmartREST 経由での通信を開始すると仮定します。デバイスは認証情報を取得した後、SmartREST プロキシに対し、テンプレートが登録済みであるかを問い合わせます。テンプレートがサーバー上で見つからない場合、デバイスはテンプレートを単一の静的テキスト リクエストとして Things Cloud へ送信します。この手順が完了したら、このテンプレートを使用する同類のデバイスはすべて、テンプレートをサーバーに再送しなくても、SmartREST を使用する通信を開始することができます。
この例は、変換プロセス概要も例示しています。「Template 1」において、"%%"
はプレースホルダーであり、これを SmartREST プロキシが埋めます。"time"
はサーバー側タイムスタンプに置き換えられます(下記参照)。残りのプレースホルダーは、リクエストデータに埋め込まれます。リクエスト例における行 1,200,20.5
は、次のように解釈されます。
- 最初のカラムは、使用するテンプレート(この例では Template 1)を参照します。
200
はテンプレート内の最初のプレースホルダーを指し、この例で言えば"source"
要素内の ID を指します(メジャーメントを送信するデバイス ID)。20.5
はテンプレート内の 2 番目のプレースホルダーを指し、この例では温度メジャーメントの値に置き換えられます。
基本的な SmartREST プロトコル
すべての SmartREST リクエストの基本構造は、次の通りです。
- 最終的にどのように変換されるかに関係なく、リクエストはすべてエンドポイント /s 宛の POST リクエストになります。
- 標準の HTTP「Authorization」ヘッダーを使用してクライアントを認証します。
- 付加的な「X-Id:」ヘッダーを使用して、クライアントの実装をデバイスタイプ(
Device_1.0
など)またはテンプレート登録プロセスで返却された識別子として指定します。 - リクエスト本体は、カンマ区切り値形式のテキスト行を含みます。各行は、標準の Things Cloud REST API に対する 1 件のリクエストに相当します。
- レスポンスは常に「200 OK」です。
- レスポンス本体も同じく、カンマ区切り値からなる行を含みます。行は、特定のリクエストに関する Things Cloud REST APIからのレスポンスに相当します。
上記の例で言えば、SmartREST リクエストは次のようになります。
POST /s HTTP/1.1
Authorization: <AUTHORIZATION>
X-Id: Device_1.0
1,200,20.5
これに呼応するレスポンス例として、次が挙げられます。
HTTP/1.1 200 OK
Transfer-Encoding: chunked
20,0
リクエストとレスポンスを照合するため、レスポンス行には、エラーコードの次に、レスポンスに対応するリクエストを示す行が含まれます。この例で言えば、20
は「OK」を意味し、0
はリクエストの 1 行目を指します。
テンプレートの登録方法は?
前述の通り、クライアントは SmartREST を使用する場合、まず、SmartREST テンプレートがすでにサーバーにとって既知であるかどうかを尋ねます。これは、次のような空の SmartREST リクエストを使用して行われます。
POST /s HTTP/1.1
Authorization: <AUTHORIZATION>
X-Id: Device_1.0
デバイス実装が既知であれば、レスポンスは ID を返し、この ID はその後のリクエストにおける「X-Id」ヘッダーの「簡略表現」として使用することができます。
HTTP/1.1 200 OK
20,<id>
デバイス実装が未知の場合、レスポンスは次のようになります。
HTTP/1.1 200 OK
40,"No template for this X-ID"
この場合、あなたのデバイス実装で使用するすべてのテンプレートを作成します。
POST /s HTTP/1.1
Authorization: <AUTHORIZATION>
X-Id: Device_1.0
10,1,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,,%%,NOW UNSIGNED NUMBER,{ "time": "%%", "type": ... }
この例では、10
は要求テンプレートを指します(一方、11
は応答テンプレートを指します)。このテンプレートは 1
番なので、このテンプレートを使用する SmartREST リクエストは最初の列に「1」が付くことになります。このテンプレートはエンドポイント /measurement/measurements 宛の POST
リクエストを参照し、コンテンツ種別は application/vnd.com.nsn.cumulocity.measurement+json
となります。このテンプレートで使用されるプレースホルダーは %%
です。プレースホルダーはタイムスタンプ(NOW
)と、符号なし数値および一般数値です。最後に、最後の列には、入力され送信されることになる POST リクエストのテンプレート本体を格納します。
レスポンスはどのように扱われますか?
上記の例では、リクエストとリクエスト テンプレートの取り扱いを例示しました。レスポンスの場合、JSONPath 表現が Things Cloud REST レスポンスを CSV に変換します。例えば、デバイスにディスプレイ画面があり、メッセージをその画面に表示できるとしましょう。メッセージを更新するためのオペレーションは次のようになります。
{
"c8y_Message": {
"text": "Hello, world!"
},
"creationTime": "2019-02-25T08:32:45.435+01:00",
"deviceId": "8789602",
"status": "PENDING"
}
クライアント側では、デバイスは主に表示されることになるテキストを知る必要があります。JSONPath では、次の構文を使用して text
プロパティを抽出します。
$.c8y_Message.text
この構文では、$
はデータ構造のルートを指し、ドット(.
)はデータ構造からの要素を選択します。オプションについて詳しくは、JSONPath のリファレンスを参照してください。
デバイスは通常、自らに関連するオペレーションと、PENDING 状態のオペレーションをすべて問い合わせます。そうしたクエリに対する Things Cloud の標準レスポンスは、次のようになります。
{
"operations": [{
"c8y_Message": {
"text": "Hello, world!"
},
"creationTime": "2014-02-25T08:32:45.435+01:00",
"deviceId": "8789602",
"status": "PENDING"
}, {
"c8y_Relay": {
"status": "OPEN"
}
}]
}
つまり、レスポンスには、さまざまな種類を有するオペレーションのリストが含まれます。そうした構造に対処するには、次の応答テンプレートを使用します。
11,2,$.operations,$.c8y_Message,$.c8y_Message.text
これは値ごとに説明すると、以下のような意味になります。
- 11: これは応答テンプレートです。
- 2: テンプレート番号は 2 番です。
- $.operations: このレスポンスはリストであり、リストのプロパティは
operations
です。 - $.c8y_Message: このテンプレートは
c8y_Message
プロパティを持つレスポンスに適用されます。 - $.c8y_Message.text: テキストはメッセージから抽出され、返されることになります。
結果、SmartREST クライアントは、次のレスポンスを返されることになります。
HTTP/1.1 200 OK
2,0,"Hello, world!"
このレスポンスは、表示メッセージを変換するためのテンプレートである「Template 2」を使用して作成されました。レスポンスは、最初に送られたリクエストを参照します。実際に設定されるメッセージは「Hello, world!」です。